﻿using System;
using EzDesk.Core.Model;
using EzDesk.DesktopClient.Model;
using EzDesk.DesktopClient.Event;
using EzDesk.DesktopClient.ServiceLocator.ClientTokenService;
using EzDesk.DesktopClient.ServiceLocator.CoreClientLoginService;
using System.Threading;
using EzDesk.Generic;

namespace EzDesk.DesktopClient
{
    public interface IUserManagement
    {
        string UserToken { get; set; }
        UserProfile LogUser { get; }
        UserState LogUserState { get; }
        void Login(string uid, string pwd);
        void Logout();
        string GetUrlWithUserToken(string url);
    }


    public class UserManagement : ManagementBase<UserManagement>, IUserManagement
    {
        private string _userToken;
        private DateTime _lastGetUserTokenDatetime = DateTime.MinValue;
        private Timer _timer;

        private IClientTokenService ClientTokenService
        {
            get { return ServiceLocator.ServiceFactory.TokenClientService; }
        }
        private ICoreClientLoginService CoreClientLoginService
        {
            get { return ServiceLocator.ServiceFactory.LoginService; }
        }

        public string UserToken
        {
            get
            {
                var dateTimeDiff = DateTime.Now - _lastGetUserTokenDatetime;
                if (dateTimeDiff.TotalMinutes > 20)
                    _userToken = ClientTokenService.RequestToken(LogUser.Id);

                return _userToken;
            }
            set
            {
                _userToken = value;
            }
        }

        public UserProfile LogUser
        {
            get;
            private set;
        }


        public UserState LogUserState
        {
            get;
            private set;
        }

        public UserManagement()
            : base()
        {
            InitProperty();
        }

        private void InitProperty()
        {
            LogUserState = new UserState();
        }

        public void Login(string uid, string pwd)
        {
            ThreadPool.QueueUserWorkItem(
                callback =>
                {
                    try
                    {
                        UserProfile userProfile = this.CoreClientLoginService.Login(uid, pwd);
                        if (userProfile == null)
                        {
                            LoginFaild("用户名或者密码错误", "user");
                        }
                        else
                        {
                            InitUserInfo(userProfile);
                            PublishLoginSuccessMessage();
                            InitTimer();
                        }
                    }
                    catch (Exception exp)
                    {
                        LogEx.ERROR("UserManagement", exp.Message, exp);
                        LoginFaild(exp.Message, "error");
                    }

                });
        }

        private void InitTimer()
        {
            _timer = new Timer(obj => RefreshUserStatusFromServer(), null, 2000, 5000);
        }

        private void RefreshUserStatusFromServer()
        {
            try
            {
                var userProfile = CoreClientService.GetUserProfileById(CurrentUser.Id);
                InitUserInfo(userProfile);
                UserStatusChangedEvent.Instance.Publish(userProfile);
            }
            catch (Exception ex)
            {
                LogEx.TRACE("TodoManagment", ex.Message);
            }
        }

        public void Logout()
        {
            if (_timer != null)
            {
                _timer.Dispose();
                _timer = null;
            }
            LogoutEvent.Instance.Publish(new LogoutArgs());
            SetCurrentUserDisable();
        }

        private void SetCurrentUserDisable()
        {
            LogUserState.IsAvailable = false;
        }


        private void InitUserInfo(UserProfile userProfile)
        {
            LogUser = userProfile;
            LogUser.HeadUrl = "http://" + CoreClientService.GetClientBaseUrl() + LogUser.HeadUrl;
            UserToken = ClientTokenService.RequestToken(userProfile.Id);
            LogUserState.IsAvailable = true;
        }

        private void PublishLoginSuccessMessage()
        {
            var args = new LoginArgs
            {
                IsSuccess = true,
                Message = "Success!"
            };
            LoginEvent.Instance.Publish(args);
            LoginedEvent.Instance.Publish(args);
        }

        private void LoginFaild(string information, string failedType)
        {
            LoginFailedEvent.Instance.Publish(new LoginFailedArgs() { Information = information, Type = failedType });
        }

        public string GetUrlWithUserToken(string url)
        {
            string userTokenPairString = "ez_auth_token=" + UserToken;
            string[] urlElement = url.Split('#');

            url = urlElement[0].Contains("?")
               ? urlElement[0] + "&" + userTokenPairString
               : urlElement[0] + "?" + userTokenPairString;
            if (urlElement.Length == 2) url += "#" + urlElement[1];

            return url;
        }
    }

}
